package com.ecommerce.user.service.impl;

import com.ecommerce.common.exception.BusinessException;
import com.ecommerce.common.util.JwtUtil;
import com.ecommerce.user.controller.UserController;
import com.ecommerce.user.dto.*;
import com.ecommerce.user.entity.User;
import com.ecommerce.user.dto.UserMapper;
import com.ecommerce.user.repository.UserRepository;
import com.ecommerce.user.service.UserService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.reactive.function.client.WebClient;

import jakarta.servlet.http.HttpServletRequest;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;
    private final UserMapper userMapper;
    private final BCryptPasswordEncoder passwordEncoder;
    private final WebClient webClient;
    private final RestTemplate restTemplate;

    @Value("${auth.service.url:http://localhost:8081}")
    private String authServiceUrl;

    @Override
    @Transactional
    public UserResponse register(UserRegisterRequest registerRequest) {
        log.info("用户注册请求: {}", registerRequest.getUsername());

        // 首先调用认证服务的注册接口
        try {
            Map<String, Object> authRegisterRequest = new HashMap<>();
            authRegisterRequest.put("username", registerRequest.getUsername());
            authRegisterRequest.put("password", registerRequest.getPassword());
            authRegisterRequest.put("email", registerRequest.getEmail());

            // 调用认证服务注册接口
            Map<String, Object> authResponse = webClient.post()
                    .uri("/api/auth/register")
                    .contentType(MediaType.APPLICATION_JSON)
                    .bodyValue(authRegisterRequest)
                    .retrieve()
                    .bodyToMono(Map.class)
                    .block();

            log.info("认证服务注册成功: {}", authResponse);
            
            // 认证服务注册成功后，同步创建用户服务记录
            // 检查用户名是否已存在（双重检查）
            if (userRepository.existsByUsername(registerRequest.getUsername())) {
                log.warn("用户服务中用户名已存在: {}", registerRequest.getUsername());
                return getUserByUsername(registerRequest.getUsername());
            }

            // 检查邮箱是否已存在（双重检查）
            if (userRepository.existsByEmail(registerRequest.getEmail())) {
                log.warn("用户服务中邮箱已存在: {}", registerRequest.getEmail());
                throw new BusinessException("邮箱已被注册");
            }

            // 创建用户服务记录（密码为空，因为密码由认证服务管理）
            User user = new User();
            user.setUsername(registerRequest.getUsername());
            user.setPassword(""); // 密码由认证服务管理，用户服务不需要存储
            user.setEmail(registerRequest.getEmail());
            user.setRoles(Collections.singleton("USER"));

            // 保存用户
            user = userRepository.save(user);
            log.info("用户服务注册成功: {}", user.getUsername());

            return userMapper.entityToResponseDto(user);
            
        } catch (Exception e) {
            log.error("调用认证服务注册失败: {}", e.getMessage());
            if (e.getMessage() != null && e.getMessage().contains("用户名已存在")) {
                throw new BusinessException("用户名已存在");
            } else if (e.getMessage() != null && e.getMessage().contains("邮箱已被注册")) {
                throw new BusinessException("邮箱已被注册");
            } else {
                throw new BusinessException("注册失败: " + e.getMessage());
            }
        }
    }

    @Override
    public UserLoginResponse login(UserLoginRequest loginRequest) {
        log.info("用户登录请求: {}", loginRequest.getUsername());

        // 首先调用认证服务验证用户名和密码
        try {
            Map<String, Object> authLoginRequest = new HashMap<>();
            authLoginRequest.put("username", loginRequest.getUsername());
            authLoginRequest.put("password", loginRequest.getPassword());

            // 调用认证服务登录接口
            Map<String, Object> authResponse = webClient.post()
                    .uri("/api/auth/login")
                    .contentType(MediaType.APPLICATION_JSON)
                    .bodyValue(authLoginRequest)
                    .retrieve()
                    .bodyToMono(Map.class)
                    .block();

            log.info("认证服务登录成功: {}", authResponse);
            
            // 认证服务登录成功后，获取用户信息
            User user = userRepository.findByUsername(loginRequest.getUsername())
                    .orElseThrow(() -> new BusinessException("用户不存在"));

            // 从认证服务响应中获取token
            String token = (String) authResponse.get("token");
            if (token == null) {
                // 如果认证服务没有返回token，自己生成一个
                List<String> rolesList = user.getRoles().stream().collect(Collectors.toList());
                token = JwtUtil.generateToken(user.getUsername(), rolesList);
            }
            
            // 构建响应
            UserResponse userResponse = userMapper.entityToResponseDto(user);
            UserLoginResponse loginResponse = new UserLoginResponse(token, userResponse);
            
            log.info("用户登录成功: {}", user.getUsername());
            return loginResponse;
            
        } catch (Exception e) {
            log.error("调用认证服务登录失败: {}", e.getMessage());
            throw new BusinessException("用户名或密码错误");
        }
    }

    @Override
    public UserResponse getUserById(Long userId) {
        log.info("根据ID获取用户信息: {}", userId);

        // 权限验证 - 确保用户只能访问自己的信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.isAuthenticated() && !authentication.getPrincipal().equals("anonymousUser")) {
            String currentUsername = authentication.getName();
            
            // 尝试通过用户名获取用户信息
            User currentUser = null;
            try {
                currentUser = userRepository.findByUsername(currentUsername)
                        .orElseThrow(() -> new BusinessException("当前用户不存在"));
            } catch (BusinessException e) {
                // 如果通过用户名找不到用户，可能是网关传递的用户信息
                log.warn("通过用户名{}找不到用户，可能是因为用户信息来自网关，跳过数据库用户验证", currentUsername);
            }
            
            // 检查是否是管理员或访问自己的信息
            boolean isAdmin = authentication.getAuthorities().stream()
                    .anyMatch(auth -> auth.getAuthority().equals("ROLE_ADMIN"));
            
            // 如果找到了当前用户，检查ID是否匹配
            if (currentUser != null) {
                log.info("当前用户: {}, ID: {}, 请求用户ID: {}", currentUsername, currentUser.getId(), userId);
                if (!isAdmin && !currentUser.getId().equals(userId)) {
                    log.warn("权限验证失败: 用户 {} 尝试访问用户 {} 的信息", currentUser.getId(), userId);
                    throw new BusinessException("无权访问其他用户信息");
                }
            } else {
                // 如果找不到当前用户，但用户已认证，可能是网关传递的用户信息
                // 这种情况下，我们信任网关的认证结果，允许用户访问信息
                log.info("网关用户访问个人信息，用户名: {}, 请求用户ID: {}", currentUsername, userId);
                
                // 从认证信息中获取用户ID进行比较
                Object principal = authentication.getPrincipal();
                if (principal instanceof org.springframework.security.core.userdetails.User) {
                    org.springframework.security.core.userdetails.User userDetails = 
                            (org.springframework.security.core.userdetails.User) principal;
                    // 检查用户ID是否匹配
                    if (!isAdmin && !userDetails.getUsername().equals(userId.toString())) {
                        log.warn("网关用户权限验证失败: 用户 {} 尝试访问用户 {} 的信息", userDetails.getUsername(), userId);
                        throw new BusinessException("无权访问其他用户信息");
                    }
                }
            }
        }

        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));
        
        // 获取响应DTO并确保字段名兼容性
        UserResponse response = userMapper.entityToResponseDto(user);
        
        // 设置别名字段以确保兼容性
        response.setUserId(response.getId()); // 设置userId别名
        response.setPhoneNumber(response.getPhone()); // 设置phoneNumber别名
        response.setAvatarUrl(response.getAvatar()); // 设置avatarUrl别名
        response.setNickName(response.getNickname()); // 设置nickName别名
        
        log.info("用户信息获取成功: {}", user.getUsername());
        return response;
    }

    @Override
    public UserResponse getUserByUsername(String username) {
        log.info("根据用户名获取用户信息: {}", username);

        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new BusinessException("用户不存在"));
        
        return userMapper.entityToResponseDto(user);
    }

    @Override
    @Transactional
    public UserResponse updateProfile(Long userId, UpdateProfileRequest updateRequest) {
        log.info("更新用户信息: {}", userId);

        // 权限验证 - 确保用户只能更新自己的信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.isAuthenticated() && !authentication.getPrincipal().equals("anonymousUser")) {
            String currentUsername = authentication.getName();
            
            // 尝试通过用户名获取用户信息
            User currentUser = null;
            try {
                currentUser = userRepository.findByUsername(currentUsername)
                        .orElseThrow(() -> new BusinessException("当前用户不存在"));
            } catch (BusinessException e) {
                // 如果通过用户名找不到用户，可能是网关传递的用户信息
                log.warn("通过用户名{}找不到用户，可能是因为用户信息来自网关，跳过数据库用户验证", currentUsername);
            }
            
            // 检查是否是管理员或更新自己的信息
            boolean isAdmin = authentication.getAuthorities().stream()
                    .anyMatch(auth -> auth.getAuthority().equals("ROLE_ADMIN"));
            
            // 如果找到了当前用户，检查ID是否匹配
            if (currentUser != null) {
                if (!isAdmin && !currentUser.getId().equals(userId)) {
                    throw new BusinessException("无权更新其他用户信息");
                }
            } else {
                // 如果找不到当前用户，但用户已认证，可能是网关传递的用户信息
                // 这种情况下，我们信任网关的认证结果，但需要验证用户ID
                log.info("网关用户更新资料，用户名: {}, 请求用户ID: {}", currentUsername, userId);
                
                // 从认证信息中获取用户ID进行比较
                Object principal = authentication.getPrincipal();
                if (principal instanceof org.springframework.security.core.userdetails.User) {
                    org.springframework.security.core.userdetails.User userDetails = 
                            (org.springframework.security.core.userdetails.User) principal;
                    // 检查用户ID是否匹配
                    if (!isAdmin && !userDetails.getUsername().equals(userId.toString())) {
                        log.warn("网关用户权限验证失败: 用户 {} 尝试修改用户 {} 的资料", userDetails.getUsername(), userId);
                        throw new BusinessException("无权更新其他用户信息");
                    }
                }
            }
        }

        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));

        // 检查邮箱是否被其他用户使用
        if (updateRequest.getEmail() != null && !updateRequest.getEmail().equals(user.getEmail())) {
            if (userRepository.existsByEmailAndIdNot(updateRequest.getEmail(), userId)) {
                throw new BusinessException("邮箱已被其他用户使用");
            }
            user.setEmail(updateRequest.getEmail());
        }

        // 更新其他字段
        if (updateRequest.getPhone() != null) {
            user.setPhone(updateRequest.getPhone());
        }
        if (updateRequest.getAddress() != null) {
            user.setAddress(updateRequest.getAddress());
        }
        if (updateRequest.getNickname() != null) {
            user.setNickname(updateRequest.getNickname());
        }
        if (updateRequest.getAvatar() != null) {
            user.setAvatar(updateRequest.getAvatar());
        }

        // 先更新用户服务数据库
        user = userRepository.save(user);
        log.info("用户服务数据库更新成功: {}", userId);
        
        // 同步更新认证服务数据库
        try {
            String url = authServiceUrl + "/api/auth/update-profile/" + userId;
            
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            
            // 构建请求体，注意字段名映射
            Map<String, Object> request = new HashMap<>();
            request.put("nickName", updateRequest.getNickname());  // 用户服务的nickname对应认证服务的nickName
            request.put("phoneNumber", updateRequest.getPhone());  // 用户服务的phone对应认证服务的phoneNumber
            request.put("email", updateRequest.getEmail());
            request.put("address", updateRequest.getAddress());    // 地址字段同步
            request.put("avatarUrl", updateRequest.getAvatar());    // 用户服务的avatar对应认证服务的avatarUrl
            
            HttpEntity<Map<String, Object>> entity = new HttpEntity<>(request, headers);
            
            // 调用认证服务的用户信息更新接口
            restTemplate.put(url, entity);
            
            log.info("认证服务数据库更新成功: {}", userId);
        } catch (Exception e) {
            log.error("调用认证服务更新用户信息失败: userId={}, error={}", userId, e.getMessage(), e);
            // 这里不抛出异常，因为用户服务已经更新成功，只记录日志
            // 在实际生产环境中，可能需要根据业务需求决定是否回滚用户服务的更新
        }
        
        return userMapper.entityToResponseDto(user);
    }

    @Override
    @Transactional
    public boolean changePassword(Long userId, ChangePasswordRequest changePasswordRequest) {
        log.info("修改用户密码: {}", userId);

        // 权限验证 - 确保用户只能修改自己的密码
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated() || authentication.getPrincipal().equals("anonymousUser")) {
            log.warn("未认证用户尝试修改密码，用户ID: {}", userId);
            throw new BusinessException("未认证，无法修改密码");
        }
        
        // 检查是否是管理员
        boolean isAdmin = authentication.getAuthorities().stream()
                .anyMatch(auth -> auth.getAuthority().equals("ROLE_ADMIN"));
        
        // 管理员可以修改任意用户密码
        if (isAdmin) {
            log.info("管理员修改密码，管理员: {}, 目标用户: {}", authentication.getName(), userId);
        } else {
            // 普通用户只能修改自己的密码
            // 从JWT令牌中获取用户ID
            String authenticatedUserId = null;
            
            // 尝试从JWT令牌中获取用户ID
            if (authentication.getDetails() instanceof Map) {
                @SuppressWarnings("unchecked")
                Map<String, Object> details = (Map<String, Object>) authentication.getDetails();
                authenticatedUserId = details.get("userId") != null ? details.get("userId").toString() : null;
            }
            
            // 如果从JWT令牌中获取不到，尝试从认证对象中获取
            if (authenticatedUserId == null) {
                authenticatedUserId = authentication.getPrincipal().toString();
            }
            
            log.info("从认证对象获取用户ID: {}, 请求修改的用户ID: {}", authenticatedUserId, userId);
            
            // 验证用户ID是否匹配
            try {
                long authenticatedUserIdLong = Long.parseLong(authenticatedUserId);
                if (authenticatedUserIdLong != userId) {
                    log.warn("权限验证失败: 认证用户ID {} 与请求修改的用户ID {} 不匹配", authenticatedUserId, userId);
                    throw new BusinessException("无权修改其他用户密码");
                }
            } catch (NumberFormatException e) {
                log.warn("权限验证失败: 认证用户ID {} 格式错误", authenticatedUserId);
                throw new BusinessException("无效的用户ID");
            }
            
            log.info("用户修改自己的密码，用户: {}, 用户ID: {}", authentication.getName(), userId);
        }

        // 验证新密码和确认密码是否一致
        if (!changePasswordRequest.getNewPassword().equals(changePasswordRequest.getConfirmPassword())) {
            throw new BusinessException("新密码和确认密码不一致");
        }

        // 直接调用认证服务修改密码
        try {
            String url = authServiceUrl + "/api/auth/change-password/" + userId;
            
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            
            Map<String, String> request = new HashMap<>();
            request.put("oldPassword", changePasswordRequest.getOldPassword());
            request.put("newPassword", changePasswordRequest.getNewPassword());
            request.put("confirmPassword", changePasswordRequest.getConfirmPassword());
            HttpEntity<Map<String, String>> entity = new HttpEntity<>(request, headers);
            
            // 调用认证服务的密码修改接口
            restTemplate.put(url, entity);
            
            log.info("用户密码修改成功: {}", userId);
            return true;
        } catch (Exception e) {
            log.error("调用认证服务修改密码失败: userId={}, error={}", userId, e.getMessage(), e);
            throw new BusinessException("密码修改失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public UserResponse updateAvatar(Long userId, String avatarUrl) {
        log.info("更新用户头像: {}", userId);

        // 权限验证 - 确保用户只能更新自己的头像
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.isAuthenticated() && !authentication.getPrincipal().equals("anonymousUser")) {
            String currentUsername = authentication.getName();
            
            // 检查是否是管理员
            boolean isAdmin = authentication.getAuthorities().stream()
                    .anyMatch(auth -> auth.getAuthority().equals("ROLE_ADMIN"));
            
            // 管理员可以更新任意用户头像
            if (isAdmin) {
                log.info("管理员更新头像，管理员: {}, 目标用户: {}", currentUsername, userId);
            } else {
                // 普通用户只能更新自己的头像
                // 从请求头中获取用户ID（网关传递的用户ID）
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
                String authenticatedUserId = request.getHeader("X-User-ID");
                
                if (authenticatedUserId != null) {
                    log.info("从请求头获取用户ID: {}, 请求更新的用户ID: {}", authenticatedUserId, userId);
                }
                
                // 验证用户ID是否匹配
                if (authenticatedUserId == null || !authenticatedUserId.equals(userId.toString())) {
                    log.warn("权限验证失败: 认证用户ID {} 与请求更新的用户ID {} 不匹配", authenticatedUserId, userId);
                    throw new BusinessException("无权更新其他用户头像");
                }
                
                log.info("用户更新自己的头像，用户: {}, 用户ID: {}", currentUsername, userId);
            }
        } else {
            log.warn("未认证用户尝试更新头像，用户ID: {}", userId);
            throw new BusinessException("未认证，无法更新头像");
        }

        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));

        user.setAvatar(avatarUrl);
        user = userRepository.save(user);
        
        log.info("用户头像更新成功: {}", userId);
        return userMapper.entityToResponseDto(user);
    }

    @Override
    @Transactional
    public void syncUser(UserController.SyncUserRequest syncRequest) {
        try {
            log.info("开始同步用户数据: userId={}, username={}", syncRequest.getUserId(), syncRequest.getUsername());
            
            // 检查用户ID是否已存在
            if (userRepository.existsById(syncRequest.getUserId())) {
                // 用户已存在，更新用户信息
                User user = userRepository.findById(syncRequest.getUserId())
                        .orElseThrow(() -> new BusinessException("用户不存在"));
                
                // 更新用户信息（处理字段名不匹配问题）
                user.setUsername(syncRequest.getUsername());
                user.setEmail(syncRequest.getEmail());
                // 处理phoneNumber与phone字段的映射
                user.setPhone(syncRequest.getPhoneNumber());
                // 处理地址字段
                user.setAddress(syncRequest.getAddress());
                // 处理nickName与nickname字段的映射
                user.setNickname(syncRequest.getNickName());
                user.setUpdatedAt(LocalDateTime.now());
                
                userRepository.save(user);
                log.info("用户信息更新成功: {}", user.getId());
            } else {
                // 检查用户名是否已存在
                if (userRepository.existsByUsername(syncRequest.getUsername())) {
                    log.warn("用户名已存在，跳过同步: {}", syncRequest.getUsername());
                    return;
                }

                // 检查邮箱是否已存在
                if (syncRequest.getEmail() != null && userRepository.existsByEmail(syncRequest.getEmail())) {
                    log.warn("邮箱已存在，跳过同步: {}", syncRequest.getEmail());
                    return;
                }
                
                // 用户不存在，创建新用户
                User user = new User();
                user.setId(syncRequest.getUserId()); // 使用认证服务的用户ID
                user.setUsername(syncRequest.getUsername());
                user.setEmail(syncRequest.getEmail());
                // 处理phoneNumber与phone字段的映射
                user.setPhone(syncRequest.getPhoneNumber());
                // 处理地址字段
                user.setAddress(syncRequest.getAddress());
                // 处理nickName与nickname字段的映射
                user.setNickname(syncRequest.getNickName());
                user.setPassword(""); // 密码在认证服务中管理，这里设置为空
                user.setAvatar(""); // 默认头像
                user.setCreatedAt(LocalDateTime.now());
                user.setUpdatedAt(LocalDateTime.now());
                // 设置默认角色
                user.setRoles(Collections.singleton("ROLE_USER"));
                
                userRepository.save(user);
                log.info("用户创建成功: {}", user.getId());
            }
        } catch (Exception e) {
            log.error("同步用户数据失败: userId={}, username={}, error={}", 
                     syncRequest.getUserId(), syncRequest.getUsername(), e.getMessage(), e);
            throw new BusinessException("用户数据同步失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public void syncPassword(Long userId, String encodedPassword) {
        try {
            log.info("同步用户密码: userId={}", userId);
            
            User user = userRepository.findById(userId)
                    .orElseThrow(() -> new BusinessException("用户不存在"));
            
            // 更新密码（认证服务已加密的密码）
            user.setPassword(encodedPassword);
            user.setUpdatedAt(LocalDateTime.now());
            
            userRepository.save(user);
            log.info("用户密码同步成功: {}", userId);
        } catch (Exception e) {
            log.error("同步用户密码失败: userId={}, error={}", userId, e.getMessage(), e);
            throw new BusinessException("用户密码同步失败: " + e.getMessage());
        }
    }

    /**
     * 同步密码到认证服务
     * @param userId 用户ID
     * @param encodedPassword 已加密的密码
     */
    private void syncPasswordToAuthService(Long userId, String encodedPassword) {
        try {
            String url = authServiceUrl + "/api/auth/sync-password/" + userId;
            
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            
            Map<String, String> request = new HashMap<>();
            request.put("encodedPassword", encodedPassword);
            HttpEntity<Map<String, String>> entity = new HttpEntity<>(request, headers);
            
            // 调用认证服务的密码同步接口
            restTemplate.postForObject(url, entity, String.class);
            
            log.info("密码同步到认证服务成功: userId={}", userId);
        } catch (Exception e) {
            log.error("密码同步到认证服务失败: userId={}, error={}", userId, e.getMessage(), e);
            throw new BusinessException("密码同步到认证服务失败: " + e.getMessage());
        }
    }

    // ===== 管理员相关方法实现 =====

    @Override
    public Page<UserResponse> getUsers(String keyword, String userType, Boolean status, Pageable pageable) {
        log.info("管理员获取用户列表，关键词: {}, 用户类型: {}, 状态: {}", keyword, userType, status);
        
        // 构建查询条件
        Page<User> userPage;
        if (keyword != null && !keyword.trim().isEmpty()) {
            // 根据关键词搜索用户名、邮箱或手机号
            userPage = userRepository.findByUsernameContainingOrEmailContainingOrPhoneContaining(
                    keyword, keyword, keyword, pageable);
        } else if (userType != null && !userType.trim().isEmpty()) {
            // 根据用户类型筛选
            userPage = userRepository.findByUserType(userType, pageable);
        } else if (status != null) {
            // 根据状态筛选
            userPage = userRepository.findByEnabled(status, pageable);
        } else {
            // 获取所有用户
            userPage = userRepository.findAll(pageable);
        }
        
        // 转换为响应DTO
        List<UserResponse> userResponses = userPage.getContent().stream()
                .map(userMapper::entityToResponseDto)
                .collect(Collectors.toList());
        
        return new org.springframework.data.domain.PageImpl<>(userResponses, pageable, userPage.getTotalElements());
    }

    @Override
    @Transactional
    public UserResponse createUser(UpdateUserRequest userRequest) {
        log.info("管理员创建用户: {}", userRequest.getUsername());
        
        // 检查用户名是否已存在
        if (userRepository.existsByUsername(userRequest.getUsername())) {
            throw new BusinessException("用户名已存在");
        }
        
        // 检查邮箱是否已存在
        if (userRepository.existsByEmail(userRequest.getEmail())) {
            throw new BusinessException("邮箱已被注册");
        }
        
        // 创建用户
        User user = new User();
        user.setUsername(userRequest.getUsername());
        user.setEmail(userRequest.getEmail());
        user.setPhone(userRequest.getPhone());
        user.setNickname(userRequest.getNickname());
        user.setAvatar(userRequest.getAvatar());
        user.setUserType(userRequest.getUserType() != null ? userRequest.getUserType() : "USER");
        user.setEnabled(userRequest.getEnabled() != null ? userRequest.getEnabled() : true);
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());
        
        // 设置密码
        if (userRequest.getPassword() != null && !userRequest.getPassword().isEmpty()) {
            user.setPassword(passwordEncoder.encode(userRequest.getPassword()));
        } else {
            user.setPassword("");
        }
        
        // 设置角色 - 使用可变的HashSet避免UnsupportedOperationException
        Set<String> roles = new HashSet<>();
        if ("ADMIN".equals(userRequest.getUserType())) {
            roles.add("ROLE_ADMIN");
        } else {
            roles.add("ROLE_USER");
        }
        user.setRoles(roles);
        
        user = userRepository.save(user);
        
        // 同步到认证服务 - 使用注册接口，因为认证服务没有sync-user接口
        try {
            Map<String, Object> authRequest = new HashMap<>();
            authRequest.put("username", user.getUsername());
            authRequest.put("password", userRequest.getPassword());
            authRequest.put("email", user.getEmail());
            
            webClient.post()
                    .uri("/api/auth/register")
                    .contentType(MediaType.APPLICATION_JSON)
                    .bodyValue(authRequest)
                    .retrieve()
                    .bodyToMono(Map.class)
                    .block();
                    
            log.info("用户同步到认证服务成功: {}", user.getUsername());
        } catch (Exception e) {
            log.error("用户同步到认证服务失败: {}", user.getUsername(), e);
            // 不回滚，因为用户服务已经创建成功
        }
        
        return userMapper.entityToResponseDto(user);
    }

    @Override
    @Transactional
    public UserResponse updateUser(Long userId, UpdateUserRequest userRequest) {
        log.info("管理员更新用户: {}", userId);
        
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));
        
        // 检查用户名是否被其他用户使用
        if (!user.getUsername().equals(userRequest.getUsername()) && 
            userRepository.existsByUsername(userRequest.getUsername())) {
            throw new BusinessException("用户名已存在");
        }
        
        // 检查邮箱是否被其他用户使用
        if (!user.getEmail().equals(userRequest.getEmail()) && 
            userRepository.existsByEmail(userRequest.getEmail())) {
            throw new BusinessException("邮箱已被注册");
        }
        
        // 更新用户信息
        user.setUsername(userRequest.getUsername());
        user.setEmail(userRequest.getEmail());
        user.setPhone(userRequest.getPhone());
        user.setNickname(userRequest.getNickname());
        user.setAvatar(userRequest.getAvatar());
        user.setUserType(userRequest.getUserType());
        user.setEnabled(userRequest.getEnabled());
        user.setUpdatedAt(LocalDateTime.now());
        
        // 更新角色 - 使用可变的HashSet避免UnsupportedOperationException
        Set<String> roles = new HashSet<>();
        if ("ADMIN".equals(userRequest.getUserType())) {
            roles.add("ROLE_ADMIN");
        } else {
            roles.add("ROLE_USER");
        }
        user.setRoles(roles);
        
        user = userRepository.save(user);
        
        // 同步到认证服务 - 使用更新用户资料接口，因为认证服务没有sync-user接口
        try {
            Map<String, Object> authRequest = new HashMap<>();
            authRequest.put("username", user.getUsername());
            authRequest.put("email", user.getEmail());
            
            webClient.put()
                    .uri("/api/auth/update-profile/" + user.getId())
                    .contentType(MediaType.APPLICATION_JSON)
                    .bodyValue(authRequest)
                    .retrieve()
                    .bodyToMono(Map.class)
                    .block();
                    
            log.info("用户信息同步到认证服务成功: {}", user.getUsername());
        } catch (Exception e) {
            log.error("用户信息同步到认证服务失败: {}", user.getUsername(), e);
            // 不回滚，因为用户服务已经更新成功
        }
        
        return userMapper.entityToResponseDto(user);
    }

    @Override
    @Transactional
    public boolean deleteUser(Long userId) {
        log.info("管理员删除用户: {}", userId);
        
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));
        
        userRepository.delete(user);
        
        // 同步删除到认证服务
        try {
            webClient.delete()
                    .uri("/api/auth/users/" + userId)
                    .retrieve()
                    .bodyToMono(Map.class)
                    .block();
                    
            log.info("用户从认证服务删除成功: {}", user.getUsername());
        } catch (Exception e) {
            log.error("用户从认证服务删除失败: {}", user.getUsername(), e);
            // 不回滚，因为用户服务已经删除成功
        }
        
        return true;
    }

    @Override
    @Transactional
    public boolean batchDeleteUsers(List<Long> userIds) {
        log.info("管理员批量删除用户: {}", userIds);
        
        List<User> users = userRepository.findAllById(userIds);
        userRepository.deleteAll(users);
        
        // 同步批量删除到认证服务
        try {
            Map<String, Object> authRequest = new HashMap<>();
            authRequest.put("ids", userIds);
            
            webClient.post()
                    .uri("/api/auth/users/batch-delete")
                    .contentType(MediaType.APPLICATION_JSON)
                    .bodyValue(authRequest)
                    .retrieve()
                    .bodyToMono(Map.class)
                    .block();
                    
            log.info("用户批量删除同步到认证服务成功: {} 个用户", users.size());
        } catch (Exception e) {
            log.error("用户批量删除同步到认证服务失败: {}", e.getMessage(), e);
            // 不回滚，因为用户服务已经删除成功
        }
        
        return true;
    }

    @Override
    @Transactional
    public boolean updateUserStatus(Long userId, boolean enabled) {
        log.info("管理员更新用户状态: {}, 状态: {}", userId, enabled);
        
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));
        
        user.setEnabled(enabled);
        user.setUpdatedAt(LocalDateTime.now());
        userRepository.save(user);
        
        // 同步状态到认证服务
        try {
            Map<String, Object> authRequest = new HashMap<>();
            authRequest.put("userId", userId);
            authRequest.put("enabled", enabled);
            
            webClient.put()
                    .uri("/api/auth/users/" + userId + "/status")
                    .contentType(MediaType.APPLICATION_JSON)
                    .bodyValue(authRequest)
                    .retrieve()
                    .bodyToMono(Map.class)
                    .block();
                    
            log.info("用户状态同步到认证服务成功: {}, 状态: {}", user.getUsername(), enabled);
        } catch (Exception e) {
            log.error("用户状态同步到认证服务失败: {}", user.getUsername(), e);
            // 不回滚，因为用户服务已经更新成功
        }
        
        return true;
    }

    @Override
    @Transactional
    public boolean resetUserPassword(Long userId) {
        log.info("管理员重置用户密码: {}", userId);
        
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));
        
        // 生成默认密码
        String defaultPassword = "123456";
        String encodedPassword = passwordEncoder.encode(defaultPassword);
        
        // 同步到认证服务
        try {
            Map<String, Object> authRequest = new HashMap<>();
            authRequest.put("userId", userId);
            authRequest.put("encodedPassword", encodedPassword);
            
            webClient.put()
                    .uri("/api/auth/users/" + userId + "/reset-password")
                    .contentType(MediaType.APPLICATION_JSON)
                    .bodyValue(authRequest)
                    .retrieve()
                    .bodyToMono(Map.class)
                    .block();
                    
            log.info("用户密码重置同步到认证服务成功: {}", user.getUsername());
        } catch (Exception e) {
            log.error("用户密码重置同步到认证服务失败: {}", user.getUsername(), e);
            throw new BusinessException("密码重置失败: " + e.getMessage());
        }
        
        return true;
    }

    @Override
    public UserStatsResponse getUserStats() {
        log.info("获取用户统计信息");
        
        long totalUsers = userRepository.count();
        long enabledUsers = userRepository.countByEnabled(true);
        long disabledUsers = userRepository.countByEnabled(false);
        long normalUsers = userRepository.countByUserType("USER");
        long adminUsers = userRepository.countByUserType("ADMIN");
        
        // 获取今日新增用户（假设有createdAt字段）
        LocalDateTime todayStart = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
        long todayNewUsers = userRepository.countByCreatedAtAfter(todayStart);
        
        // 获取本周新增用户
        LocalDateTime weekStart = LocalDateTime.now().with(java.time.DayOfWeek.MONDAY).withHour(0).withMinute(0).withSecond(0);
        long weekNewUsers = userRepository.countByCreatedAtAfter(weekStart);
        
        // 获取本月新增用户
        LocalDateTime monthStart = LocalDateTime.now().withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        long monthNewUsers = userRepository.countByCreatedAtAfter(monthStart);
        
        return UserStatsResponse.builder()
                .totalUsers(totalUsers)
                .todayNewUsers(todayNewUsers)
                .weekNewUsers(weekNewUsers)
                .monthNewUsers(monthNewUsers)
                .activeUsers(enabledUsers) // 假设启用的用户就是活跃用户
                .normalUsers(normalUsers)
                .vipUsers(0L) // 暂时不支持VIP用户
                .adminUsers(adminUsers)
                .enabledUsers(enabledUsers)
                .disabledUsers(disabledUsers)
                .build();
    }
}